package com.ficus.road.maintain.service;

import com.ficus.road.maintain.core.model.RoadIce;
import com.ficus.road.maintain.core.model.WarningDetail;
import com.ficus.road.maintain.core.model.ZhongHai;
import com.ficus.road.maintain.core.model.zh.bridgehotel.BridgeHotel;
import com.ficus.road.maintain.core.model.zh.bridgehotel.BridgeHotelVO;
import com.ficus.road.maintain.core.model.zh.bridgehotel.BridgeHotelWarning;
import com.ficus.road.maintain.core.model.zh.roadice.RoadIceVO;
import com.ficus.road.maintain.core.model.zh.roadice.RoadIceWarning;
import com.ficus.road.maintain.dao.BridgeHotelDao;
import com.ficus.road.maintain.dao.BridgeHotelWarningDao;
import com.ficus.road.maintain.dao.RoadIceDao;
import com.ficus.road.maintain.dao.ZhongHaiDao;
import com.ficus.road.maintain.util.MyDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xiawen yang
 * @date 2021/10/15 下午2:30
 */
@Component
@Slf4j
public class ZhongHaiService {

    @Autowired
    private ZhongHaiDao zhongHaiDao;
    @Autowired
    private ZhonghaiClient zhonghaiClient;
    @Autowired
    private BridgeHotelDao bridgeHotelDao;
    @Autowired
    private RoadIceDao roadIceDao;
    @Autowired
    private BridgeHotelWarningDao bridgeHotelWarningDao;
    @Value("${zhonghai.ip}")
    private String ip;
    @Value("${zhonghai.port}")
    private int port;
    @Value("${zhonghai.webServicePort}")
    private int webServicePort;

    public String getZhongHaiData(ZhongHai zhonghai) {
        //先查数据库中的数据
        Query query = new Query(Criteria.where("type").is(zhonghai.getType()).and("arg").is(zhonghai.getArg()).and("enable").is(true));
        query.with(new Sort(Sort.Direction.DESC, "time_stamp")).skip(0).limit(1);
        ZhongHai dbData = zhongHaiDao.findOne(query);
        //数据库查到数据就返回，查不到就再调一次中海接口
        if (Objects.nonNull(dbData)) {
            return dbData.getData();
        }
        String zhonghaiData = zhonghaiClient.callZhongHaiInterface(zhonghai.getType(), zhonghai.getArg());
        //数据库查不到，调了一次中海接口又查不到，就可能返回空字符串
        return zhonghaiData;
    }

    public List<BridgeHotelVO> getBridgeHotelInfo() {
        List<BridgeHotelVO> bridgeHotelVOS = new ArrayList<>();
        List<BridgeHotel> bridgeHotels = bridgeHotelDao.findAll();
        List<BridgeHotelWarning> bridgeHotelWarnings = bridgeHotelWarningDao.findAll();
        Map<String, List<BridgeHotelWarning>> warningMap = bridgeHotelWarnings.stream().sorted(Comparator.comparing(BridgeHotelWarning::getWarningTime).reversed()).collect(Collectors
                .groupingBy(BridgeHotelWarning::getDeviceId));
        bridgeHotels.forEach(bridgeHotel -> {
            BridgeHotelVO bridgeHotelVO = BridgeHotelVO.builder().deviceId(bridgeHotel.getDeviceId()).monitorType(bridgeHotel.getMonitorType())
                    .roadId(bridgeHotel.getRoadId()).pictureAddress(bridgeHotel.getPictureAddress())
                    .longitude(bridgeHotel.getLongitude() != null ? Double.parseDouble(bridgeHotel.getLongitude()) : null)
                    .latitude(bridgeHotel.getLatitude() != null ? Double.parseDouble(bridgeHotel.getLatitude()) : null).status(true).build();
//            BridgeHotelWarning bridgeHotelWarning = bridgeHotelWarningDao.findOne(new Query(Criteria.where("device_id").is(bridgeHotel.getDeviceId()))
//                    .with(new Sort(Sort.Direction.DESC, "warning_time")).skip(0).limit(1));
            if (ObjectUtils.isNotEmpty(warningMap) && ObjectUtils.isNotEmpty(warningMap.get(bridgeHotel.getDeviceId()))) {
                BridgeHotelWarning bridgeHotelWarning = warningMap.get(bridgeHotel.getDeviceId()).get(0);
                WarningDetail warningDetail = WarningDetail.builder().pictureAddress(bridgeHotelWarning.getWarningPic())
                        .roadName(bridgeHotel.getAddress()).time(MyDateUtil.dateFormatStr(bridgeHotelWarning.getWarningTime(), "yyyy-MM-dd HH:mm")).build();
                bridgeHotelVO.setWarningDetail(warningDetail);
                bridgeHotelVO.setStatus(false);
            }
            bridgeHotelVOS.add(bridgeHotelVO);
        });
        return bridgeHotelVOS;
    }

    public List<WarningDetail> getBridgeHotelWarning() {
        List<WarningDetail> warningDetailList = new ArrayList<>();
        Query query = new Query();
        query.with(new Sort(Sort.Direction.DESC, "warning_time"));
        List<BridgeHotelWarning> bridgeHotelWarningList = bridgeHotelWarningDao.findByQuery(query);
        bridgeHotelWarningList.forEach(bridgeHotelWarning -> {
            BridgeHotel fetch = bridgeHotelDao.fetch(bridgeHotelWarning.getDeviceId());
            WarningDetail warningDetail = WarningDetail.builder().deviceId(bridgeHotelWarning.getDeviceId()).pictureAddress(bridgeHotelWarning.getWarningPic())
                    .time(MyDateUtil.dateFormatStr(bridgeHotelWarning.getWarningTime(), "yyyy-MM-dd HH:mm")).roadName(fetch.getAddress()).build();
            warningDetailList.add(warningDetail);
        });
        return warningDetailList;
    }

    public List<RoadIceVO> getRoadIceInfo() {
        List<RoadIceVO> roadIceVOS = new ArrayList<>();
        List<RoadIce> roadIces = roadIceDao.findAll();
        roadIces.forEach(roadIce -> {
            RoadIceVO roadIceVO = RoadIceVO.builder().deviceId(roadIce.getDeviceId())
                    .deviceName(roadIce.getDeviceName()).time(roadIce.getTime())
                    .roadStatus(roadIce.getRoadStatus()).temperature(roadIce.getTemperature() != null ? Double.parseDouble(roadIce.getTemperature()) : null)
                    .salinity(roadIce.getSalinity() != null ? Double.parseDouble(roadIce.getSalinity()) : null)
                            .stagnant(roadIce.getStagnant() != null ? Double.parseDouble(roadIce.getStagnant()) : null)
                    .snow(roadIce.getSnow() != null ? Double.parseDouble(roadIce.getSnow()) : null)
                            .iceTheory(roadIce.getIceTheory() != null ? Double.parseDouble(roadIce.getIceTheory()) : null)
                    .iceProbability(roadIce.getIceProbability() != null ? Double.parseDouble(roadIce.getIceProbability()) : null)
                    .longitude(roadIce.getLgt() != null ? Double.parseDouble(roadIce.getLgt()) : null)
                    .latitude(roadIce.getLat() != null ? Double.parseDouble(roadIce.getLat()) : null)
                    .status(roadIce.getStatus() != null ? Integer.parseInt(roadIce.getStatus()) : null).build();

            if(roadIce.getStatus().equals("1")){
                RoadIceWarning roadIceWarning = RoadIceWarning.builder().alertStatus(roadIce.getAlertStatus())
                        .time(roadIce.getTime()).iceDepth(roadIce.getIceDepth() != null ? Double.parseDouble(roadIce.getIceDepth()) : null)
                        .status(roadIce.getStatus() != null ? Integer.parseInt(roadIce.getStatus()) : null).build();
                roadIceVO.setWarningDetail(roadIceWarning);
            }
            roadIceVOS.add(roadIceVO);
        });
        return roadIceVOS;
    }

}
